#ifndef __thinvm_thread__
#define __thinvm_thread__

#include "thinvm.h"

namespace thinvm
{
	struct tprocess_t;

	struct tthread_t : IA32_CPU, refable_impl_t
	{
	protected:

		refp<tprocess_t>		_process;

		bx_uint32_t				_tid;

		bx_uint32_t				_teb_base;

		bx_uint32_t				_stack_low;

		bx_uint32_t				_stack_high;

	public:

		tthread_t( tprocess_t * proc );

		//////////////////////////////////////////////////////////////////////////
		//
		//	create
		//

		long					create( uint32_t tid, bx_uint32_t entry, bx_uint32_t teb_base, bx_uint32_t stack_low, bx_uint32_t stack_size );

		//////////////////////////////////////////////////////////////////////////
		//
		//	stack operation
		//

		bool					push( bx_uint32_t val );
		bool					ret_n( Bit16u n );
		bool					ret_eax_n( Bit16u n, bx_uint32_t ret_val );

		//////////////////////////////////////////////////////////////////////////
		//
		//	exec 
		//

		size_t					execute( size_t steps, size_t check_bits );

		//////////////////////////////////////////////////////////////////////////
		//
		//	inline functions
		//

		inline bool				set_reg_value( size_t index, bx_uint32_t val ) { gen_reg[index].dword.erx = val; return true; }
		inline void				set_xip( bx_uint32_t val ) { EIP = val; }
		inline void				set_xsp( bx_uint32_t val ) { ESP = val; }
		inline void				set_xax( bx_uint32_t val ) { EAX = val; }

		inline bx_uint32_t		xip() { return EIP; }
		inline bx_uint32_t		xsp() { return ESP; }
		inline bx_uint32_t		xax() { return EAX; }

		inline const bx_stop_reason_t * 
								stop_reason() { return &StopReason; }

		inline size_t			thistid() { return _tid; }
		inline size_t			tebbase() { return _teb_base; }
		inline tprocess_t * process() { return _process; };
		inline size_t			stack_laddr() { return _stack_low; };
		inline size_t			stack_haddr() { return _stack_high; };

	public:

		//////////////////////////////////////////////////////////////////////////
		//
		//	callbacks
		//

		virtual void			init_teb_page( void * host ) {}

	};
};

#endif